package com.tanhua.dubbo.api.impl;

import cn.hutool.core.date.DateUtil;
import com.tanhua.dubbo.api.UserLikeApi;
import com.tanhua.dubbo.api.VoiceApi;
import com.tanhua.dubbo.pojo.Voice;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

@DubboService(version = "1.0.0")
public class VoiceApiImpl implements VoiceApi {
    public static final String VOICE_SEND_REDIS_KEY_PREFIX = "VOICE_SEND_REMAIN_";
    public static final String VOICE_RECEIVE_REDIS_KEY_PREFIX = "VOICE_RECEIVE_REMAIN_";
    private static final String VOICE_LIST_REDISKEY = "VOICE_LIST_";

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserLikeApi userLikeApi;




    @Override
    public Boolean save(Long userId, String name) {

        String rediskey = this.getSendRedisKey(userId);
        // 每天第一次发送语音
        if (null == this.redisTemplate.opsForValue().get(rediskey)) {
            this.redisTemplate.opsForValue().set(rediskey, "9");
        } else {
            this.redisTemplate.opsForValue().decrement(rediskey, 1);
        }

        Voice voice = new Voice();
        voice.setId(ObjectId.get());
        voice.setUserId(userId);
        voice.setSoundUrl(name);
        voice.setCreated(System.currentTimeMillis());

        Voice save = this.mongoTemplate.save(voice);

        return true;
    }

    private String getSendRedisKey(Long userId) {
        return VOICE_SEND_REDIS_KEY_PREFIX + DateUtil.today() + "_" + userId;
    }

    private String getReceiveRedisKey(Long userId) {
        return VOICE_RECEIVE_REDIS_KEY_PREFIX + DateUtil.today() + "_" + userId;
    }

    @Override
    public List<Voice> queryRandomVoice(Long userId) {
        Long maxDate = new Date().getTime();
        Long minDate = DateUtil.offsetDay(new Date(), -1).getTime();

        // 排除喜欢和不喜欢的人
        List<Long> excludeList = this.getExcludeList(userId);

        // 排除当日已经接受过的语音ID
        Set<Object> keys = this.redisTemplate.opsForHash().keys(VOICE_LIST_REDISKEY + userId);


        Query query = Query.query(Criteria.where("userId").nin(excludeList)
                .and("id").nin(keys)
                .andOperator(Criteria.where("created").lte(maxDate),
                        Criteria.where("created").gte(minDate)));

        return this.mongoTemplate.find(query, Voice.class);

    }

    public Long queryRemainTimes(Long userId) {
        String rediskey = this.getReceiveRedisKey(userId);
        if (null == this.redisTemplate.opsForValue().get(rediskey)) {
            this.redisTemplate.opsForValue().set(rediskey, "10");
        }
        return this.redisTemplate.opsForValue().decrement(rediskey, 1);
    }

    @Override
    public List<Voice> queryDefaultVoice(Long userId) {
        // 排除喜欢和不喜欢的人
        List<Long> likeList = getExcludeList(userId);

        // 排除当日已经接受过的语音ID
        Set<Object> keys = this.redisTemplate.opsForHash().keys(VOICE_LIST_REDISKEY + userId);
        Query query = Query.query(Criteria.where("userId").nin(likeList)
                .and("id").nin(keys)).limit(20);
        return this.mongoTemplate.find(query, Voice.class);
    }

    private List<Long> getExcludeList(Long userId) {

        ArrayList<Long> excludeList = new ArrayList<>();
        List<Long> notLikeList = this.userLikeApi.queryNotLikeList(userId);
        List<Long> likeList = this.userLikeApi.queryLikeList(userId);
        excludeList.addAll(notLikeList);
        excludeList.addAll(likeList);
        excludeList.add(userId);
        return likeList;
    }
}
